#!/usr/bin/python2.4
#
# Copyright 2011 Google Inc. All Rights Reserved.

"""One-line documentation for flood module.

A detailed description of flood.
"""

__author__ = 'arb@google.com (Anthony Baxter)'

RIVER = 'javascript:PopupRiver'
RIVERLABELS = ['Station No','River Height (m)','Time of Observation','Flood Class','Tendency','Minor (m)','Moderate (m)','Major (m)']
RIVERELEMENTS = ['name', 'station','lat', 'long','height',
                 'floodClass','tendency', 'time','minorHeight','moderateHeight','majorHeight']

from BeautifulSoup import BeautifulSoup as BS
from django.utils import simplejson
import urllib
import datetime

# qld
maps = { 'qld' : ('north', 'central', 'seast', 'widebay', 'border', 'gulf',
                  'west'),
        'nsw' : ('northcoast', 'northwest', 'outerwest', 'southcoast',
                 'centralwest', 'greatersydney'),
        'vic' : ('wimmera_mallee', 'glenelg_hopkins', 'corangamite', 'port_phillip', 
                 'west_gippsland', 'north_east', 'east_gippsland', 'goulburn_broken', 
                 'north_central'),
        'sa'  : ('southeast', 'adelaide'),
        'tas' : ('northwestern', 'northern', 'southern', 'hobart', 'launceston')
        }
# nsw
#northcoast midnorth greatersydney southcoast northwest centralwest southwest outerwest

# vic
#wimmera_mallee glenelg_hopkins corangamite port_philip west_gippsland north_east east_gippsland goulburn_broken north_central

def loadMaps():
  l = []
  for state in maps:
    for map in maps[state]:
      url = urllib.urlopen('http://www.bom.gov.au/' + state + '/flood/' + map + '.shtml')

      bs = BS(url.read())

      for a in bs.findAll('area'):
        js = a['onmouseover']
        href = a['href']
        if js.startswith('javascript:PopupRiver'):
          js = js[len(RIVER)+1:-1]
          els = js.split(',')
          els = [x.strip("'").strip() for x in els]
          out = {'href': "http://www.bom.gov.au" + href}
          #raise Exception
          for n, v in zip(RIVERELEMENTS, els):
            out[n] = v
        
          l.append(out)

  # TODO(arb): sanitise the JSON
  return makeKml(l)
  #return simplejson.dumps(l)

# HERE BE DRAGONS
# TODO(jmcgill): Replace with Fusion Tables when we have time to play with OAuth
# and verify that upload/drop is reliable.
def makeStyle(document, image, id):
  text = """<Style id="%s">
    <IconStyle>
      <Icon>
        <href>%s</href>
      </Icon>
    </IconStyle>
  </Style>
  """ % (id, image)
  document.append(text)

def floodLevelToStyle(level):
  # jmcgill, best coder, or bestEST coder?
  mapping = {
    'Unknown': 'gray',
    'No Classification': 'gray',
    'Major': 'red',
    'Moderate': 'orange',
    'Below Minor': 'ltblue',
    'Below Flood Level': 'ltblue',
    'Minor': 'green'
  }

  return '#' + mapping[level]

def makePoint(document, point):
  style = floodLevelToStyle(point['floodClass'])
  text = """<Placemark>
    <styleUrl>%s</styleUrl>
    <name>%s</name>
    <description>%s;%s;%s;%s</description>
    <Point>
      <coordinates>%s,%s</coordinates>
    </Point>
  </Placemark>""" % (style, point['name'], point['height'], point['tendency'],
                     point['time'], point['floodClass'], point['long'], point['lat'])
  document.append(text)

def makeKml(data):
  # Why bother with the DOM when you can concat strings?
  document = []
  document.append("""<?xml version="1.0" encoding="utf-8"?>
  <kml xmlns="http://earth.google.com/kml/2.0">
  <Document><name>Queensland River Flood Levels</name>""")

  # Create icon styles.
  base = "http://mapvisage.appspot.com/static/floodmap/images/rivers/"
  makeStyle(document, base + "red_smaller.png", "red")
  makeStyle(document, base + "green_smaller.png", "green")
  makeStyle(document, base + "orange_smaller.png", "orange")
  makeStyle(document, base + "ltblue_smaller.png", "ltblue")
  makeStyle(document, base + "gray_smaller.png", "gray")

  # Add points - TODO(jmcgill) Infowindows?
  for point in data:
    makePoint(document, point)

  document.append("</Document></kml>")
  return "".join(document)

def updateMap():
  from google.appengine.api import memcache
  # TODO(arb): also store in datastore
  memcache.set('qld', loadMaps())

def showMap():
  from google.appengine.api import memcache
  return memcache.get('qld')

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class UpdatePage(webapp.RequestHandler):
  def get(self):
    updateMap()
    self.response.headers['Content-Type'] = 'text/plain'
    self.response.out.write('OK')

class ShowPage(webapp.RequestHandler):
  def get(self):
    self.response.headers['Content-Type'] = 'application/vnd.google-earth.kml+xml'
    now = datetime.datetime.utcnow()
    expires = now + datetime.timedelta(minutes=5)
    self.response.headers['Expires'] = (
        expires.strftime('%a, %d %b %Y %H:%M:%S GMT'))
    self.response.headers['Cache-Control'] = 'public, max_age=300'
    self.response.out.write(showMap())

application = webapp.WSGIApplication([('/flood/update__', UpdatePage),
                                      ('/flood/json9', ShowPage)], debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()
